package sample.ws.service;

import org.springframework.stereotype.Service;
import sample.ws.entity.AccessRuleRepository;
import sample.ws.entity.IPRuleRepository;
import sample.ws.entity.ServiceAccessRuleEntity;
import sample.ws.entity.ServiceEntity;
import sample.ws.entity.ServiceIPRuleEntity;
import sample.ws.entity.ServiceRepository;
import sample.ws.model.RuleModel;
import sample.ws.util.AccessComponent;
import sample.ws.util.LocalCacheUtils;

import java.time.LocalDateTime;
import java.util.List;

/**
 * IServiceImpl..
 *
 * @author Lizhong
 * @date 2019/7/15
 */
@Service
public class IServiceImpl implements IService {
    private final ServiceRepository serviceRepository;
    private final IPRuleRepository ipRuleRepository;
    private final AccessRuleRepository accessRuleRepository;
    private final AccessComponent accessComponent;
    private final LocalCacheUtils cacheUtils;

    public IServiceImpl(ServiceRepository serviceRepository, IPRuleRepository ipRuleRepository,
                        AccessRuleRepository accessRuleRepository, AccessComponent accessComponent, LocalCacheUtils cacheUtils) {
        this.serviceRepository = serviceRepository;
        this.ipRuleRepository = ipRuleRepository;
        this.accessRuleRepository = accessRuleRepository;
        this.accessComponent = accessComponent;
        this.cacheUtils = cacheUtils;
    }

    @Override
    public boolean add(ServiceEntity serviceEntity) {
        serviceRepository.save(serviceEntity);
        cacheUtils.updateSqlCache(serviceEntity);
        return true;
    }

    @Override
    public void update() {

    }

    @Override
    public void delete() {

    }

    @Override
    public ServiceEntity findServiceById(Long id) {
        ServiceEntity serviceEntity = serviceRepository.findAllByIdAndEnableIsTrue(id);
        return serviceEntity;

    }

    @Override
    public ServiceEntity findByName(String name) {
        return serviceRepository.findByName(name);
    }

    @Override
    public List<ServiceEntity> findServiceList(String category, Integer page, Integer size) {
        // TODO: 2019/7/17 分页关键字
        return serviceRepository.findAllByEnableIsTrue();
    }

    @Override
    public boolean openServiceById(Long id) {
        ServiceEntity serviceById = findServiceById(id);
        serviceById.setState(1);
        serviceRepository.save(serviceById);
        return true;
    }

    @Override
    public boolean closeServiceById(Long id) {
        ServiceEntity serviceById = findServiceById(id);
        serviceById.setState(-1);
        serviceRepository.save(serviceById);
        return true;
    }

    @Override
    public boolean putIpBackListById(ServiceIPRuleEntity ipRuleEntity) {
        ServiceIPRuleEntity serviceIPRuleEntity = null;
        if (ipRuleEntity.getId() == null) {
            serviceIPRuleEntity = ipRuleRepository.findByIdAndEnableIsTrue(ipRuleEntity.getId());
            if (serviceIPRuleEntity == null) throw new RuntimeException("更新IP规则异常");
            serviceIPRuleEntity.setIp(ipRuleEntity.getIp());
        } else {
            serviceIPRuleEntity = new ServiceIPRuleEntity(null, ipRuleEntity.getIp(), ipRuleEntity.getServiceId(), true, LocalDateTime.now());
        }
        ipRuleRepository.save(serviceIPRuleEntity);
        accessComponent.updateIpRule(ipRuleEntity.getServiceId());
        return true;
    }

    @Override
    public boolean deleteIpBackListById(Long id) {
        ServiceIPRuleEntity byIdEnableIsTrue = ipRuleRepository.findByIdAndEnableIsTrue(id);
        byIdEnableIsTrue.setEnable(false);
        ipRuleRepository.save(byIdEnableIsTrue);
        accessComponent.updateIpRule(byIdEnableIsTrue.getServiceId());
        return false;
    }

    @Override
    public List<ServiceIPRuleEntity> getIpBackList() {
        return ipRuleRepository.findAllByEnableIsTrue();
    }

    @Override
    public boolean putAccessRule(Long id, RuleModel rule) {
        ServiceAccessRuleEntity serviceAccessRuleEntity = null;
        ServiceAccessRuleEntity byServiceIdAndEnableIsTrue =
                accessRuleRepository.findByServiceIdAndEnableIsTrue(id);
        if (byServiceIdAndEnableIsTrue != null) {
            serviceAccessRuleEntity = byServiceIdAndEnableIsTrue;
        } else {
            serviceAccessRuleEntity = new ServiceAccessRuleEntity();
            serviceAccessRuleEntity.setServiceId(id);
            serviceAccessRuleEntity.setCreateTime(LocalDateTime.now());
        }
        serviceAccessRuleEntity.setDuration(rule.getDuration());
        serviceAccessRuleEntity.setTimes(rule.getTimes());
        accessRuleRepository.save(serviceAccessRuleEntity);
        accessComponent.updateAccessRule(rule);
        return true;
    }

    @Override
    public boolean deleteAccessRule(Long serviceId) {
        ServiceAccessRuleEntity byServiceIdAndEnableIsTrue = accessRuleRepository.findByServiceIdAndEnableIsTrue(serviceId);
        byServiceIdAndEnableIsTrue.setEnable(false);
        accessRuleRepository.save(byServiceIdAndEnableIsTrue);
        accessComponent.updateAccessRule(new RuleModel(serviceId, -1, -1));
        return true;
    }

    @Override
    public List<ServiceAccessRuleEntity> getAccessRules() {
        return accessRuleRepository.findAllByEnableIsTrue();
    }

}
